package com.ardf.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.ardf.service.CardWebSocketService;
import jakarta.websocket.*;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

@Service
@Component
@Slf4j
@ServerEndpoint(value = "/topic/ws/demo/{uid}") //标识该类为 WebSocket 服务端点
public class CardWebsocketServiceImpl implements CardWebSocketService {
    //    连接池的数量
    private static final Map<Long, Session> SESSION_POOL = new HashMap<>();


    @Override
    @OnOpen
    public void onOpen(Session session, @PathParam(value="uid") Long uid){
        if (Objects.isNull(uid)) {
            log.warn("当前连接session:{}为空：", JSONObject.toJSONString(session));
            return;
        }
        SESSION_POOL.put(uid, session);
        log.info("连接uid:{},连接池的大小:{}", uid, SESSION_POOL.size());
    }

    @Override
    @OnClose
    public void onClose(Session session, @PathParam(value="uid") Long uid) {
        if (Objects.isNull(uid)) {
            log.warn("当前连接session:{}为空：", JSONObject.toJSONString(session));
            return;
        }


        try {
            Session removeSession = SESSION_POOL.remove(uid);//根据uid删除连接池中的连接
            if (session != null) { //连接池不空
                session.close();
            }
            if(removeSession!=null && removeSession.isOpen()){ //当前用户session连接不为空且在开启状态
                removeSession.close();
            }
            log.info("关闭的uid:{},当前连接池大小:{}",uid,SESSION_POOL.size());

        } catch (IOException e) {
            log.error("用户关闭失败:{},e:{}",uid,e.getMessage(),e);
        }

    }

    @Override
    @OnMessage
    public void onMessage(Session session, @PathParam(value="uid") Long uid, String message){
        log.info("收到用户消息，uid:{},消息:{}",uid,message);
    }

    @Override
    @OnError
    public void onError(Session session,@PathParam(value="uid") Long uid,Throwable e){
        log.error("发送异常，uid:{},消息:{}",uid,e.getMessage(),e);
    }

    @Override
    public void sendAllMessage(String message) {
        log.info("广播的消息：{}",message);
        if(SESSION_POOL.isEmpty()){ //连接池为空
            return;
        }
        //遍历连接池广播消息
        SESSION_POOL.forEach((uid,session)->{
            if(session.isOpen()){
                session.getAsyncRemote().sendText(message);
            }
        });
    }

    @Override
    public void sendMessageToUsers(Set<Long> uids, String message) {
        log.info("向多用户发送消息，uids:{},发送的消息是：{}",message,message);
        uids.forEach((uid)-> sendMessageToUser(uid,message)); //向单个用户发送消息
    }

    @Override
    public void sendMessageToUser(Long uid, String message) {
        Session session = SESSION_POOL.get(uid);
        if(session!=null && session.isOpen()){
            session.getAsyncRemote().sendText(message);
            log.info("向用户:{}发送消息为：{}",uid,message);
        }
    }

}
